import * as history from 'History';
import { Stream, MemoryStream } from 'xstream';
import { VNode, DOMSource } from '@cycle/dom';
import { HTTPSource, RequestOptions } from '@cycle/http';
import { TimeSource } from '@cycle/time';
import { StateSource } from 'cycle-onionify';
import { Location } from 'history';

/**
 * 资源，基类
 */
export interface Sources {
    DOM : DOMSource;
    HTTP : HTTPSource;
    Time : TimeSource;
    history : MemoryStream<Location>
}

/**
 * Root组件
 */
export interface RootSinks {
    DOM : Stream<VNode>;
    HTTP : Stream<RequestOptions>;
}

/**
 * Sinks: 控件组
 * Partial: 映射类型，把必需类型映射成可选的
 */
export type Sinks = Partial<RootSinks>;
export type Component = (s : Sources) => Sinks;

// APP

/**
 * App的状态
 */
export type AppState = {
};
/**
 * App的还原器
 */
export type AppReducer = (prev : AppState) => AppState;

/**
 * App的资源
 */
export type AppSources = Sources & { onion : StateSource<AppState> };

/**
 * App的组件
 */
export type AppSinks = Sinks & { onion : Stream<any> };

// TODO

/**
 * TodoList的state
 */
export interface TodoListState {
    /**
     * 输入框的值
     */
    inputValue: string,
    /**
     * Todo列表
     */
    list: Array<TodoState>,
    /**
     * 底部过滤器文字
     */
    filter: string,
    /**
     * 过滤方法
     */
    filterFn: (item : TodoState) => boolean,
}
/**
 * TodoList的Reducer
 */
export type TodoListReducer = (prev : TodoListState) => TodoListState;

/**
 * TodoList的Sources
 */
export type TodoListSources = Sources & { onion : StateSource<TodoListState> };

/**
 * TodoList的Sinks
 */
export type TodoListSinks = Sinks & { onion : Stream<TodoListReducer | {}> };

/**
 * TodoList的Action
 */
export interface TodoListAction {
    /**
     * 路由改变
     */
    changeRoute$: Stream<string>,
    /**
     * 输入框更新
     */
    updateInputValue$: Stream<string>,
    /**
     * 输入取消
     */
    cancelInput$: Stream<null>,
    /**
     * 插入Todo
     */
    insertTodo$: Stream<string>,
    /**
     * 切换所有
     */
    toggleAll$: Stream<boolean>,
    /**
     * 删除完成
     */
    deleteCompleted$: Stream<null>
}

/**
 * Todo的State
 */
export interface TodoState {
    key: number,
    /**
     * Todo的文字
     */
    title: string,
    /**
     * 已完成
     */
    completed: boolean,
    /**
     * 编辑中
     */
    editing: boolean
}

/**
 * Todo的Action
 */
export interface TodoAction {
    /**
     * 开始编辑
     */
    startEdit$: Stream<null>,
    /**
     * 结束编辑
     */
    doneEdit$: Stream<string>,
    /**
     * 取消编辑
     */
    cancelEdit$: Stream<null>,
    /**
     * 切换
     */
    toggle$: Stream<boolean>,
    /**
     * 删除
     */
    destroy$: Stream<null>
}

/**
 * Todo的Reducer
 */
export type TodoReducer = (prev : TodoState) => TodoState | undefined;

/**
 * Todo的Sources
 */
export type TodoSources = Sources & { onion : StateSource<TodoState> };

/**
 * Todo的Sinks
 */
export type TodoSinks = Sinks & { onion : Stream<TodoReducer> };

/**
 * TodoList的Sources
 */
export type TodoListCollectionSources = Sources & { onion : StateSource<TodoState[]> };